package com.enterprise.viewer.client.presenter;

import com.enterprise.viewer.client.event.MasonryEvent;
import com.enterprise.viewer.client.event.ServiceEvent;
import com.enterprise.viewer.client.event.ServiceEvent.CATEGORY;
import com.enterprise.viewer.client.event.ServiceEvent.EVENTTYPE;
import com.enterprise.viewer.client.event.ServiceEvent.NAME;
import com.enterprise.viewer.client.event.ServiceEvent._Event;
import com.enterprise.viewer.client.view.Masonry;
import com.enterprise.viewer.shared.contentproviders.ContentProvider;
import com.enterprise.viewer.shared.contentproviders.ContentProviderCategory;
import com.enterprise.viewer.shared.contentproviders.ContentProviders;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.IFrameElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.StackLayoutPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.event.shared.binder.EventBinder;


public class RootPresenter implements Presenter{

	//see http://www.gwtproject.org/articles/mvp-architecture-2.html	
	//see https://github.com/google/gwteventbinder

	interface MyEventBinder extends EventBinder<RootPresenter> {}
	static MyEventBinder eventBinder = GWT.create(MyEventBinder.class);

	public interface Display {
		Label getHeader();
		Label getFooter();
		StackLayoutPanel getNavBar();
		HorizontalPanel getButtonBar();
		Masonry getMasonry();
		Widget asWidget();
	}

	private final SimpleEventBus eventBus;
	private final Display display;
	private final MasonryPresenter masonrypresenter;


	public RootPresenter(SimpleEventBus eventBus, Display view){
		this.eventBus = eventBus;
		this.display = view;
		eventBinder.bindEventHandlers(this, eventBus);
		bind();
		masonrypresenter = new MasonryPresenter(eventBus, display.getMasonry());
	}

	@Override
	public void go(HasWidgets container) {
		container.clear();
		container.add(display.asWidget());
	}

	private void bind(){		

		//on startup request the content provider list
		ServiceEvent.fireEvent(eventBus, EVENTTYPE.REQUEST, CATEGORY.GET, NAME.CONTENTPROVIDERS, null);
		ServiceEvent.fireEvent(eventBus, EVENTTYPE.REQUEST, CATEGORY.GET, NAME.SERVICES, null);

		eventBus.addHandler(ServiceEvent.TYPE, new ServiceEvent._EventHandler() {

			@Override
			public void onChange(_Event event) {
				if(event.getType().compareTo(EVENTTYPE.RESPONSE) == 0 || event.getType().compareTo(EVENTTYPE.BROADCAST) == 0){
					if(event.getCategory().compareTo(CATEGORY.GET) == 0){
						if(event.getName().compareTo(NAME.CONTENTPROVIDERS) == 0){
							if(event.getParams() != null && event.getParams().length == 1){
								updateNavBar((ContentProviders) event.getParams()[0]);
							}
						}
						else if(event.getName().compareTo(NAME.SERVICES) == 0){
							if(event.getParams() != null && event.getParams().length == 1){
								updateButtonBar((ContentProviders) event.getParams()[0]);
							}
						}
					}
				}
			}});

		History.addValueChangeHandler(new ValueChangeHandler<String>() {

			@Override
			public void onValueChange(ValueChangeEvent<String> event) {
				//String token = event.getValue();
			}
		});
	}

	private class LoadProviderClickHandler implements ClickHandler {
		private String url;		

		public LoadProviderClickHandler(String url) {
			this.url = url;
		}

		@Override
		public void onClick(ClickEvent event) {
			Object[] params = new Object[1];
			params[0] = this.url;
			//MasonryEvent.fireEvent(eventBus, MasonryEvent.EVENTTYPE.BROADCAST, MasonryEvent.CATEGORY.CHANGED, MasonryEvent.NAME.URL, params);
			/*contentpane.clear();	
			
			//http://stackoverflow.com/questions/9434836/access-frames-document-using-gwt
			//http://www.gwtproject.org/javadoc/latest/com/google/gwt/dom/client/IFrameElement.html
			
			//IFrameElement iframe = IFrameElement.as(frame.getElement());
			//iframe.getContentDocument();
			
			String s = "<iframe src='http://" + url + "' height='100%' width='100%' seamless='true' name='myframe' scrolling='no' frameborder='0'></iframe>";
			//Window.alert(s);
			contentpane.addCell(0);
			contentpane.getWidget(row, column)  .add(new HTML(s));*/
		}
	}
	
	private void updateButtonBar(ContentProviders services){
		if(services.getClass() != ContentProviders.class){
			return;
		}
		
		HorizontalPanel buttonbar = display.getButtonBar();
		buttonbar.clear();
		for(ContentProviderCategory service : services){
			buttonbar.add(new PushButton(service.getName()));
			buttonbar.add(new HTML("<span style='width: 124px;'>&nbsp;</span>"));
		}
		buttonbar.add(new HTML("<span style='width: 124px;'>&nbsp;</span>"));
	}

	private void updateNavBar(ContentProviders contentproviders){

		if(contentproviders.getClass() != ContentProviders.class){
			return;
		}

		StackLayoutPanel navbar = display.getNavBar();
		navbar.clear();
		for(ContentProviderCategory category : contentproviders){
			HTMLPanel panel = new HTMLPanel("");
			for(ContentProvider provider : category){
				panel.add(new Button(provider.getName(), new LoadProviderClickHandler(provider.getUrl())));
			}
			navbar.add(panel, new HTML(category.getName()), 25);
		}
	}
}
